<template>
  <div
    v-if="props.showText || inputDisabled || disabled"
    v-html="formData[prop]"
    style="width: 100%;"
    class="html-box"
  ></div>
  <div v-else class="editor-box">
    <Toolbar
      :editor="editorRef"
      :defaultConfig="toolbarConfig"
      :mode="mode"
      style="border-bottom: 1px solid #ccc"
    />
    <Editor
      v-model="valueHtml"
      :defaultConfig="editorConfig"
      :mode="mode"
      style="height: 390px; overflow-y: hidden;text-align: left"
      @onCreated="handleCreated"
      @onChange="handleChange"
      @customPaste="customPaste"
    />
  </div>
</template>

<script setup>
import '@wangeditor/editor/dist/css/style.css'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { ref, onMounted, watch, shallowRef, onBeforeUnmount, nextTick, inject } from "vue";
import { useDisabled, useFormItem } from 'element-plus';
import api from '@/http/api'

const emit = defineEmits(['update:modelValue', 'change'])
const props = defineProps({
  prop: String,
  options: Object,
  isClear: {
    type: Boolean,
    default: false
  },
  height: {
    type: Number,
    default: 500
  },
  mode: {
    type: String,
    default: 'default'
  },
  disabled: Boolean,
  showText: Boolean
});

const initializing = ref(true);
const formData = inject('formData');
const editorRef = shallowRef();
const loading = ref(false);
const inputDisabled = useDisabled();
const formItem = useFormItem();
const valueHtml = ref('')
const toolbarConfig = ref({});
const editorConfig = ref({MENU_CONF: []});

editorConfig.value.MENU_CONF['uploadImage'] = {
  async customUpload(file, insertFn) {
    api.upload({'file': file, type: file.type}).then((res) => {
      loading.value = false;
      insertFn(import.meta.env.VITE_IMAGE_PATH + res.data.id);
    }).catch(() => {
      loading.value = false;
    });
  }
};

const handleCreated = (editor) => {
  editorRef.value = editor;
  editor.setHtml(valueHtml.value || '');
};

const handleChange = (editor) => {
  formData.value[props.prop] = editor.getHtml();
  if (formItem && formItem.formItem) {
    nextTick(() => {
      !initializing.value && formItem.formItem.validate('change');
    });
  }
  emit('change');
};

const customPaste = (editor, event, callback) => {
  event.preventDefault();
  let content = event.clipboardData.getData('text/plain') || '';
  content = content.replace(/&nbsp;/ig, '');
  content = content.replace(/<o:p><\/o:p>/g, '');
  content = content.replace(/<o><\/o>/ig, '');
  content = content.replace(/<xml>[\s\S]*?<\/xml>/ig, '');
  content = content.replace(/<style>[\s\S]*?<\/style>/ig, '');
  content = content.replace(/<([a-zA-Z1-6]+)(\s*[^>]*)?>/ig, '<$1>');
  content = content.replace(/<span>([\s\S]*?)<\/span>/ig, '$1');
  content = content.replace(/<br\/>/g, '');
  content = content.replace(/<br>/g, '');
  editor.insertText(content);
  callback(false);
};

const init = () => {
  initializing.value = true;
  valueHtml.value = formData.value[props.prop] || '';
  nextTick(() => initializing.value = false);
};

watch(() => formData.value[props.prop], () => {
  init();
});

onMounted(() => {
  init();
});

onBeforeUnmount(() => {
  if (!inputDisabled) {
    const editor = editorRef.value;
    if (editor == null) return;

    editor.destroy();
  }
});
</script>

<style>
.w-e-toolbar {
  z-index: 503!important;
}
.w-e-menu {
  z-index: 502!important;
}
.w-e-text-container{
  z-index: 501!important;
}
</style>

<style scoped>
.html-box {
  min-height: 300px;
  max-height: 500px;
  overflow: auto;
  border-radius: 4px;
  border: 1px solid #DCDFE6;
  background: #F5F7FA;
  padding: 10px 10px;
  text-align: left;
}
.editor-box {
  border: 1px solid #ccc;
  min-height: 400px;
  flex-grow: 1;
  z-index: 10;
}
</style>
